package com.xhwl.data.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.Account;
import com.xhwl.common.pojo.cent.sdata.Enterprise;
import com.xhwl.common.pojo.cent.sdata.EnterpriseSpace;
import com.xhwl.common.pojo.cent.sdata.Organization;
import com.xhwl.common.query.cent.sdata.EnterpriseQuery;
import com.xhwl.common.vo.cent.sdata.EnterpriseSpaceDetailDTO;
import com.xhwl.common.vo.cent.sdata.EnterpriseSpaceDetailVO;
import com.xhwl.data.dao.IEnterpriseDao;
import com.xhwl.data.dao.IEnterpriseSpaceDao;
import com.xhwl.data.dao.IOrganizationDao;
import com.xhwl.data.service.IEnterpriseService;
import com.xhwl.data.service.IEnterpriseSpaceService;
import com.xhwl.data.service.IOrganizationService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: luyi
 * @Description:
 * @Date: Create in 11:31 2022/8/10
 */
@Service
public class EnterpriseSpaceImpl extends ServiceImpl<IEnterpriseSpaceDao, EnterpriseSpace> implements IEnterpriseSpaceService {

    @Autowired
    IEnterpriseDao enterpriseDao;

    @Autowired
    IEnterpriseService enterpriseService;

    @Autowired
    IOrganizationDao organizationDao;

    @Autowired
    IOrganizationService organizationService;

    @Override
    public ResultJson<List<EnterpriseSpace>> getEnterpriseSpace(EnterpriseQuery query) {
        List<EnterpriseSpace> list = getBaseMapper().getEnterpriseSpace(query);
        return ResultJson.success(list);
    }

    @Override
    public List<EnterpriseSpaceDetailVO> getEnterpriseSpaceDetail(EnterpriseSpaceDetailDTO enterpriseSpaceDetailDTO) {
        List<EnterpriseSpaceDetailVO> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(enterpriseSpaceDetailDTO.getEnterpriseIds()) || null == enterpriseSpaceDetailDTO.getOrgId())
            return result;
        // 企业信息
        List<Enterprise> enterprises = enterpriseDao.selectBatchIds(enterpriseSpaceDetailDTO.getEnterpriseIds());
        if (CollectionUtils.isEmpty(enterprises)) {
            return result;
        }
        Map<Integer, List<Enterprise>> entMap = enterprises.stream().collect(Collectors.groupingBy(Enterprise::getId));
        // 获取企业下租赁空间数据
        QueryWrapper<EnterpriseSpace> query = new QueryWrapper<>();
        query.in("enterprise_id", enterpriseSpaceDetailDTO.getEnterpriseIds());
        List<EnterpriseSpace> enterpriseSpaceList = getBaseMapper().selectList(query);
        if (CollectionUtils.isEmpty(enterpriseSpaceList))
            return result;
        // 获取企业管理员
        Map<Integer, Account> enterpriseAdmin = enterpriseService.findEnterpriseAdmin(enterpriseSpaceDetailDTO.getEnterpriseIds());
        // 递归所有orgIds的子集
        List<Organization> allChildrenNodeByParent = organizationService.list(new QueryWrapper<Organization>().eq("id", enterpriseSpaceDetailDTO.getOrgId()));
        if (!allChildrenNodeByParent.isEmpty()){
            fingAllChildren(allChildrenNodeByParent);
        }
        // 按企业进行聚合
        Map<Integer, List<EnterpriseSpace>> entSpaceMap = enterpriseSpaceList.stream().collect(Collectors.groupingBy(EnterpriseSpace::getEnterpriseId));
        entSpaceMap.forEach((enterpriseId, enterpriseSpaces) -> {
            // 取企业授权的租赁空间orgIds
            List<Integer> entSpaceOrgIds = enterpriseSpaces.stream().map(EnterpriseSpace::getOrganizationId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(allChildrenNodeByParent)) {
                List<Integer> collect = allChildrenNodeByParent.stream().map(Organization::getId).collect(Collectors.toList());
                // 过滤入参本身，剩下全是当前orgIs的子集
                List<Integer> filterOrgIds = collect.stream().filter(id -> enterpriseSpaceDetailDTO.getOrgId() != id).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(filterOrgIds)) {
                    // 入参orgIds的子集与企业授权租赁空间取交集
                    List<Integer> intersectionOrgIds = filterOrgIds.stream().filter(id -> entSpaceOrgIds.contains(id)).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(intersectionOrgIds)) {
                        QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
                        queryWrapper.select("id", "name", "level", "parent_id").in("id", intersectionOrgIds);
                        List<Organization> organizations = organizationDao.selectList(queryWrapper);
                        if (CollectionUtils.isNotEmpty(organizations)) {
                            List<Integer> levelList = organizations.stream().map(Organization::getLevel).collect(Collectors.toList());
                            // 最大等级
                            Integer maxLevel = Collections.max(levelList);
                            // 最小等级
                            Integer minLevel = Collections.min(levelList);
                            // 将 organizations 数据结构拼接 fullname
                            List<String> fullName = covertOrgFullName(maxLevel, minLevel, organizations);
                            // 组装结果返回
                            EnterpriseSpaceDetailVO enterpriseSpaceDetailVO = new EnterpriseSpaceDetailVO();
                            enterpriseSpaceDetailVO.setEnterpriseId(enterpriseId);
                            enterpriseSpaceDetailVO.setEnterpriseName(entMap.get(enterpriseId).get(0).getName());
                            enterpriseSpaceDetailVO.setSpaceName(fullName);
                            if (null != enterpriseAdmin.get(enterpriseId)){
                                enterpriseSpaceDetailVO.setContactPhone(enterpriseAdmin.get(enterpriseId).getPhone());
                            }
                            enterpriseSpaceDetailVO.setLogo(entMap.get(enterpriseId).get(0).getLogo());
                            result.add(enterpriseSpaceDetailVO);
                        }
                    }
                }
            }
        });
        return result;
    }

    /**
     * 递归查找orgIds所有子集
     * @param list
     * @return
     */
    private void fingAllChildren(List<Organization> list) {
        //过滤最高等级路址
        List<Organization> levelSortedList = list.stream().sorted(Comparator.comparing(l -> l.getLevel())).collect(Collectors.toList());
        Collections.reverse(levelSortedList);
        Integer maxlevel = levelSortedList.get(0).getLevel();
        List<Integer> orgIds = list.stream().filter(q ->q.getLevel().equals(maxlevel)).map(Organization::getId).distinct().collect(Collectors.toList());
        //查询子节点
        List<Organization> organizations = organizationService.list(new QueryWrapper<Organization>().in("parent_id", orgIds));
        List<Organization> filterOrgs = organizations.stream().filter(p -> !list.contains(p)).collect(Collectors.toList());
        //子节点不为空继续
        if (!filterOrgs.isEmpty()) {
            list.addAll(organizations);
            list.stream().distinct().collect(Collectors.toList());
            fingAllChildren(list);
        }
    }

    /**
     * 拥有层级关系的组织名称拼接
     *
     * @param maxLevel
     * @param minLevel
     * @param organizations
     * @return
     */

    private List<String> covertOrgFullName(Integer maxLevel, Integer minLevel, List<Organization> organizations) {
        List<String> fullNameList = new ArrayList<>();
        //筛选第一层级org
        Map<Integer, String> orgIdAddressMap = new HashMap<>();
        List<Organization> collect = organizations.stream().filter(p -> p.getLevel().equals(minLevel)).collect(Collectors.toList());
        for (Organization organization : collect) {
            orgIdAddressMap.put(organization.getId(), organization.getName());
        }
        Map<Integer, String> childrenAddress = getChildrenAddress(orgIdAddressMap, organizations);
        for (Integer address : childrenAddress.keySet()) {
            fullNameList.add(childrenAddress.get(address));
        }
        return fullNameList;
    }

    private Map<Integer, String> getChildrenAddress(Map<Integer, String> addressMap, List<Organization> organizations) {
        Map<Integer, String> newAddressMap = new HashMap<>();
        for (Integer orgId : addressMap.keySet()) {
            List<Organization> childrens = organizations.stream().filter(p -> p.getParentId().equals(orgId)).collect(Collectors.toList());
            if (childrens.isEmpty()) {
                newAddressMap.put(orgId, addressMap.get(orgId));
                continue;
            }
            for (Organization child : childrens) {
                newAddressMap.put(child.getId(), addressMap.get(child.getParentId()) + "-" + child.getName());
            }
            getChildrenAddress(newAddressMap, organizations);
        }
        return newAddressMap;
    }


    @Override
    public ResultJson<List<EnterpriseSpace>> getEnterpriseSpaceByQuery(EnterpriseQuery query) {
        if (Objects.isNull(query)) {
            return null;
        }
        LambdaQueryWrapper<EnterpriseSpace> wrapper = Wrappers.lambdaQuery();
        wrapper.in(EnterpriseSpace::getOrganizationId, query.getIdList());
        return ResultJson.success(list(wrapper));
    }


}
